win32: Report ScrollDC update region directly
authorAlexander Larsson <alexl@redhat.com>
Thu, 11 Apr 2013 10:12:35 +0000 (12:12 +0200)
committerAlexander Larsson <alexl@redhat.com>
Thu, 11 Apr 2013 10:12:35 +0000 (12:12 +0200)
Rather than set the window update region and repaint this region
when we get a WM_PAINT we just directly add it to the update
region. No need to roundtrip via win32.

This lets us also make sure we do this drawing in the same update
cycle. This seems especially important on Win7, because ScrollDC
seems to act kind of weird there, not using bitblt in areas where
it seemingly could, which makes scrolling look really flashy.

http://bugzilla.gnome.org/show_bug-cgi?id=674051

gdk/win32/gdkwindow-win32.c

index 95f6e16b66e3752b982e75746777e9e7672ba189..2c2e15df4098d2e434d555a49b7d182a59ed5116 100644 (file)
@@ -3330,9 +3330,8 @@ _gdk_win32_window_translate (GdkWindow *window,
                              gint       dy)
 {
   GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
-  GdkRectangle extents;
-  RECT rect;
   HRGN hrgn, area_hrgn;
+  cairo_region_t *update_region;
   HDC hdc;
   int ret;
 
@@ -3367,19 +3366,17 @@ _gdk_win32_window_translate (GdkWindow *window,
   /* Clip hdc to target region */
   API_CALL (SelectClipRgn, (hdc, area_hrgn));
 
-  cairo_region_get_extents (area, &extents);
-
-  rect.left = MIN (extents.x, extents.x - dx);
-  rect.top = MIN (extents.y, extents.y - dy);
-  rect.right = MAX (extents.x + extents.width, extents.x - dx  + extents.width);
-  rect.bottom = MAX (extents.y + extents.height, extents.y - dy  + extents.height);
-
   SetRectRgn (hrgn, 0, 0, 0, 0);
 
-  if (!ScrollDC (hdc, dx, dy, &rect, NULL, hrgn, NULL))
+  if (!ScrollDC (hdc, dx, dy, NULL, NULL, hrgn, NULL))
     WIN32_GDI_FAILED ("ScrollDC");
-  else if (!InvalidateRgn (GDK_WINDOW_HWND (window), hrgn, FALSE))
-    WIN32_GDI_FAILED ("InvalidateRgn");
+  else
+    {
+      update_region = _gdk_win32_hrgn_to_region (hrgn);
+      if (!cairo_region_is_empty (update_region))
+       _gdk_window_invalidate_for_expose (window, update_region);
+      cairo_region_destroy (update_region);
+    }
 
   /* Unset hdc clip region */
   API_CALL (SelectClipRgn, (hdc, NULL));